Skip to content

feat: replace numeric table assignment with dynamic two-floor lettere…#426

Open
jackzheng-cs wants to merge 2 commits intomainfrom
381-update-table-number-to-letter-number
Open

feat: replace numeric table assignment with dynamic two-floor lettere…#426
jackzheng-cs wants to merge 2 commits intomainfrom
381-update-table-number-to-letter-number

Conversation

@jackzheng-cs
Copy link
Contributor

Summary

@jackzheng-cs jackzheng-cs linked an issue Mar 5, 2026 that may be closed by this pull request
@michelleyeoh michelleyeoh requested a review from Copilot March 24, 2026 04:25
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates CSV ingestion table assignment to generate two-floor letter-number table labels (e.g., A3) and prioritize “Best Hardware Hack” teams on floor 1, aligning with Issue #381’s new table labeling scheme.

Changes:

  • Added a two-floor table assignment algorithm that distributes teams across lettered rows.
  • Prioritized hardware teams on floor 1 and filled remaining floor 1 capacity with non-hardware teams.
  • Replaced the previous sequential numeric table numbering assignment.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +332 to +402
// Table number assignment
const ALL_ROWS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('');

// Max teams per row on Floor 1 (Prioritize hardware teams))
const FLOOR1_MAX_PER_ROW = 5;

// Max teams per row on Floor 2
const FLOOR2_MAX_PER_ROW = 10;

/**
* Spreads teams evenly across rows, filling earlier rows first when there is a remainder
*
* Each team's tableNumber is set to e.g. "A3", "B1"
*/

function distributeAcrossRows(teams: ParsedRecord[], rows: string[]): void {
if (teams.length === 0 || rows.length === 0) return;
const baseCount = Math.floor(teams.length / rows.length);
const remainder = teams.length % rows.length;

let i = 0;
for (let rowIdx = 0; rowIdx < rows.length; rowIdx++) {
const letter = rows[rowIdx];
const rowSize = baseCount + (rowIdx < remainder ? 1 : 0);
for (let seat = 1; seat <= rowSize; seat++) {
teams[i].tableNumber = `${letter}${seat}` as any;
i++;
}
}
}

/**
* Assigns two-floor lettered table numbers:
*
* Floor 1 — Hardware Hack teams first, with leftover seats filled by other teams in .csv order.
*
* Floor 2 — remaining other teams after floor 1 spillover is accounted for.
* Rows start immediately after floor 1's last letter.
*/
function assignTableNumbers(
hardwareTeams: ParsedRecord[],
otherTeams: ParsedRecord[]
): void {
// Total row count for floor 1 for hardware teams
const floor1RowCount = Math.max(
1,
Math.ceil(hardwareTeams.length / FLOOR1_MAX_PER_ROW)
);

// How many seats are available on floor 1 vs how many hardware teams fill them.
const floor1Capacity = floor1RowCount * FLOOR1_MAX_PER_ROW;
const floor1Spillover = floor1Capacity - hardwareTeams.length;

// Pull enough other teams to fill the leftover floor 1 seats.
const floor1OtherTeams = otherTeams.slice(0, floor1Spillover);
const floor2Teams = otherTeams.slice(floor1Spillover);

const floor1Teams = [...hardwareTeams, ...floor1OtherTeams];

// Total row count for floor 2
const floor2RowCount = Math.max(
1,
Math.ceil(floor2Teams.length / FLOOR2_MAX_PER_ROW)
);

// Deligate table letters based on row counts for each floor
const floor1Rows = ALL_ROWS.slice(0, floor1RowCount);
const floor2Rows = ALL_ROWS.slice(
floor1RowCount,
floor1RowCount + floor2RowCount
);
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ALL_ROWS is limited to A–Z. If floor1RowCount or floor1RowCount + floor2RowCount exceeds 26, slice(...) will return fewer/zero rows, causing distributeAcrossRows to assign too many seats per letter and/or leave some teams without a tableNumber (since rows.length === 0 early-returns). Add an explicit guard with a clear error when required rows exceed available labels, or implement multi-letter labels (AA, AB, …) so all teams get assigned deterministically.

Copilot uses AI. Check for mistakes.
Comment on lines +353 to +358
for (let rowIdx = 0; rowIdx < rows.length; rowIdx++) {
const letter = rows[rowIdx];
const rowSize = baseCount + (rowIdx < remainder ? 1 : 0);
for (let seat = 1; seat <= rowSize; seat++) {
teams[i].tableNumber = `${letter}${seat}` as any;
i++;
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

teams[i].tableNumber = ${letter}${seat} as any; bypasses typing, but ParsedRecord.tableNumber (and the persisted Team.tableNumber) are currently typed/used as number throughout the codebase. Persisting a string like "A3" will break consumers that compare or query by numeric tableNumber. Prefer updating the relevant types and downstream consumers (API queries, floor calculations, UI) to accept the new string format, or introduce a separate field (e.g. tableLabel) while keeping tableNumber numeric.

Copilot uses AI. Check for mistakes.
Math.ceil(floor2Teams.length / FLOOR2_MAX_PER_ROW)
);

// Deligate table letters based on row counts for each floor
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor typos in comments: extra ")" in "(Prioritize hardware teams))" and "Deligate" should be "Delegate". Please fix to avoid confusion when maintaining this logic.

Suggested change
// Deligate table letters based on row counts for each floor
// Delegate table letters based on row counts for each floor

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Update table number to letter-number

3 participants